package com.hackaton.touringengine;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.repackaged.org.json.JSONArray;
import com.google.appengine.repackaged.org.json.JSONException;
import com.google.appengine.repackaged.org.json.JSONObject;
import com.hackaton.touringengine.entity.Location;
import com.hackaton.touringengine.entity.User;
import com.hackaton.touringengine.persistence.PersistenceFactory;

public class UserLocationsServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = -709015761480896905L;
	
	private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");


	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		PersistenceManager pm = PersistenceFactory.get().getPersistenceManager();
		try {
			final JSONObject jsonObject = new JSONObject(req.getParameter("post"));
			final String id = jsonObject.getString("userId");
			final User user = pm.getObjectById(User.class, KeyFactory.createKey(User.class.getSimpleName(), id));
			final int period = jsonObject.getInt("peirod");
		    Query query = pm.newQuery(Location.class);
		    query.setFilter("user == userParam && date>=timeMinimum");
		    query.setOrdering("date desc");
		    query.declareParameters("User userParam, java.util.Date timeMinimum");
		    query.setRange(0, 500);
		    final Calendar calendar = Calendar.getInstance();
		    calendar.add(Calendar.SECOND, -period);
		    Date date = calendar.getTime();
		    writeResult(resp, (List<Location>)query.executeWithArray(user, date), 0);
		} catch (Exception e) {
			writeResult(resp, null, 1);
		} finally {
			pm.close();
		}
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.doGet(req, resp);
	}

	private void writeResult(HttpServletResponse resp, List<Location> locations, int resultCode) throws IOException {
		resp.setContentType("text/plain");
		JSONObject resultJSON = new JSONObject();
		JSONObject statusJSON = new JSONObject();
		try {
			if (resultCode == 0) {
				JSONArray locationArray = new JSONArray();
				int i = 0;
				for (Location location : locations) {
					JSONObject locationJSON = new JSONObject();
					locationJSON.put("latitude", location.getLatitude());
					locationJSON.put("longitude", location.getLongitude());
					locationJSON.put("time", TIME_FORMAT.format(location.getDate()));
					if (location.getAccuracy() != null) {
						locationJSON.put("accuracy", location.getAccuracy());
					}
					if (location.getVelocity() != null) {
						locationJSON.put("velocity", location.getVelocity());
					}
					locationArray.put(i++, locationJSON);
				}
				resultJSON.put("locations", locationArray);
			}
			statusJSON.put("code", resultCode);
			resultJSON.put("status", statusJSON);
			resp.setStatus(200);
			resp.getWriter().println(resultJSON.toString());
		} catch (JSONException e1) {
			//this won't happen
		}
	}
}
